import process from 'process'
import {v4 as uuidv4} from 'uuid'
import path from 'path'
import oss from '../oss'
import logging from '../logging'
import certificate from '../certificate'
import * as glob from 'glob';
import {sizeCheck} from './sizeCheck'

// upload report to oss, return oss objectKey. If it's a html report, all files under the directory will be uploaded.
export async function uploadReport(reportPath:string): Promise<string>{
    const flowJobToken: string | undefined =
    process.env['FLOW_JOB_TOKEN']

    if (flowJobToken == undefined) {
        const errMsg = 'missing FLOW_JOB_TOKEN'
        throw new Error(errMsg)
    }

    const ossRamStsCertificate = await certificate.getOssRamStsCertificate(flowJobToken, certificate.OssBucketType.ASSETS)
    let endpoint = await oss.getEndpoint(process.env['ENDPOINT'] as string)
    if (!endpoint.startsWith('http://') && !endpoint.startsWith('https://')) {
        endpoint = 'https://' + endpoint;
    }
    const remoteStorage = new oss.OSSStorage({
        endpoint: endpoint,
        accessKeyID: ossRamStsCertificate.accessKeyId,
        accessKeySecret: ossRamStsCertificate.accessKeySecret,
        securityToken: ossRamStsCertificate.securityToken,
        bucket: ossRamStsCertificate.bucketName
    })
    logging.info(`uploading report to oss: ${endpoint}`)

    const uuid = uuidv4()
    const reportFileName = path.basename(reportPath)
    const reportDir = path.dirname(reportPath)
    let files= [reportFileName]

    // If the report is a html file, we need to upload all the files (css, image and so on) in the directory
    if(reportFileName.endsWith('.html')){
        files = await listFiles(reportDir)
    }

    await sizeCheck(reportDir, files)

    try {
        for (const file of files) {
            const objectKey = `${ossRamStsCertificate.ossPathPrefix}/${process.env['PIPELINE_ID']}/${uuid}/${file}`
            logging.debug(`uploading file ${path.join(reportDir, file)} to oss: ${objectKey}`)
            await oss.upload(remoteStorage, path.join(reportDir, file), objectKey, undefined)
        }
    } catch (e){
        logging.error(`upload report to oss failed`)
        throw e
    }

    const reportObjectKey = `${ossRamStsCertificate.ossPathPrefix}/${process.env['PIPELINE_ID']}/${uuid}/${reportFileName}`
    return reportObjectKey
}

export async function listFiles(dir: string): Promise<string[]> {
    return glob.glob('**/*',{ cwd: dir, dot: true, nodir: true})
}